home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / MiscKit1.7.1 / MiscKit / Palettes / MiscCalendarPalette / MiscCalendarView.subproj / MiscCalendarView.m < prev    next >
Text File  |  1995-04-12  |  26KB  |  1,172 lines

  1. // Copyright (C) 1995 Jon Kutemeier
  2. // Use is governed by the MiscKit license
  3.  
  4. #import <objc/List.h>
  5. #import <appkit/Application.h>
  6. #import <apps/InterfaceBuilder.h>
  7. #import <appkit/Text.h>
  8. #import <appkit/TextField.h>
  9. #import <appkit/Font.h>
  10. #import <appkit/Matrix.h>
  11. #import <appkit/Box.h>
  12. #import <appkit/color.h>
  13. #import <appkit/drag.h>
  14.  
  15. #import "misckit/MiscCalendarViewConstants.h"
  16. #import "misckit/DateDelegateProtocol.h"
  17. #import "misckit/MiscCalendarView.h"
  18.  
  19. #import "DateSelectionCell.h"
  20. #import "MiscCalendarMatrix.h"
  21.  
  22. typedef struct {
  23.     int    xdelta;
  24.     int width;
  25.     const char *value;
  26. } calHeaders;
  27.  
  28.  
  29. static calHeaders headerSpecs[] = {
  30. {0, 17, "S"},
  31. {16, 19, "M"},
  32. {17, 17, "T"},
  33. {16, 20, "W"},
  34. {18, 17, "T"},
  35. {18, 17, "F"},
  36. {17, 17, "S"},
  37. {-1, -1, ""},
  38. };
  39.  
  40. @interface MiscCalendarView (TextDelegate)
  41.  
  42. - (BOOL)textWillChange:sender;
  43. - textDidChange:sender;
  44. - (BOOL)textWillEnd:sender;
  45. - textDidEnd:sender endChar:(unsigned short)whyEnd;
  46. - textDidGetKeys:sender isEmpty:(BOOL)flag;
  47.  
  48. @end
  49.  
  50. @interface MiscCalendarView (Dragging)
  51.  
  52. - (NXDragOperation)draggingEntered:(id <NXDraggingInfo>)sender;
  53. - draggingExited:(id <NXDraggingInfo>)sender;
  54. - (NXDragOperation)draggingUpdated:(id <NXDraggingInfo>)sender;
  55. - (BOOL)prepareForDragOperation:(id <NXDraggingInfo>)sender;
  56. - (BOOL)performDragOperation:(id <NXDraggingInfo>)sender;
  57. - concludeDragOperation:(id <NXDraggingInfo>)sender;
  58.  
  59. @end
  60.  
  61. @interface MiscCalendarView (IBView)
  62.  
  63. - depositIBColor:(NXColor)aColor at:(NXPoint *)aPoint;
  64. - acceptsIBColorAt:(NXPoint *)aPoint;
  65.  
  66. @end
  67.  
  68. @interface MiscCalendarView (Private)
  69.  
  70. - _createTextFieldWithFrame:(NXRect *)textFrame 
  71.   stringValue:(const char *)aString;
  72. - _acceptColor:(NXColor)aColor at:(NXPoint *)aPoint;
  73.  
  74. @end
  75.  
  76. /* This helps us get rid of unwanted compiler warnings and serves */
  77. /* no useful purpose */
  78.  
  79. @protocol FAKEOUTCC
  80.  
  81. - getInspectorFor:object owner:owner;
  82. - cellColorMatrix;
  83.  
  84. @end
  85.  
  86.  
  87. @implementation MiscCalendarView
  88.  
  89. - finishUnarchiving
  90. {
  91.     /* This is called by IB In test interface mode. */
  92.     /* Register a timed-entry to be called right after */
  93.     /* this event-loop to do our final initialization. */
  94.  
  95.    /* only for IB */
  96.  
  97.     const char *pbTypes[] = {NXColorPboardType};
  98.  
  99.     [self registerForDraggedTypes:pbTypes count:1];
  100.     [[self window] registerForDraggedTypes:pbTypes count:1];
  101.  
  102.    if([NXApp conformsTo:@protocol(IB)])
  103.    {
  104.        [self perform:@selector(awakeFromNib)
  105.     with:nil afterDelay:0.01 cancelPrevious:NO];
  106.    }
  107.  
  108.    return self;
  109. }
  110.  
  111. - awakeFromNib
  112. {
  113.     const char *pbTypes[] = {NXColorPboardType};
  114.  
  115.     [self registerForDraggedTypes:pbTypes count:1];
  116.     [[self window] registerForDraggedTypes:pbTypes count:1];
  117.  
  118.     helvetica_11 = [Font newFont:"Helvetica" size:11 style:0
  119.                    matrix:NX_FLIPPEDMATRIX];
  120.     system_11_bold = [Font boldSystemFontOfSize:11
  121.               matrix:NX_FLIPPEDMATRIX];
  122.  
  123.     helvetica_12 = [Font newFont:"Helvetica" size:12 style:0
  124.                    matrix:NX_FLIPPEDMATRIX];
  125.     system_12_bold = [Font boldSystemFontOfSize:12
  126.               matrix:NX_FLIPPEDMATRIX];
  127.     
  128.     /* Setup standard calendar action method */
  129.  
  130.     [calendarMatrix setAction:@selector(updateDate:)];
  131.     [calendarMatrix setTarget:self];
  132.  
  133.     /* If there is a date delegate, set it */
  134.  
  135.     if (dateDelegate)
  136.       [calendarMatrix setDateDelegate:dateDelegate];
  137.     else
  138.       dateDelegate = [calendarMatrix dateDelegate];
  139.  
  140.     /* If there is an external month field, set its value to */
  141.     /* the month value */
  142.  
  143.     if (monthField && [monthField respondsTo:@selector(setStringValue:)])
  144.       [monthField setStringValue:[[calendarMatrix dateDelegate]
  145.                   monthStringValue]];
  146.  
  147.     /* If we are displaying the standard month header, set its value */
  148.     /* to the month */
  149.  
  150.     if (displayMonthHeader)
  151.       [monthSubview setStringValue:[[calendarMatrix dateDelegate]
  152.                     monthStringValue]];
  153.  
  154.     /* If there is an external year field, set its value to */
  155.     /* the year value */
  156.  
  157.     if (yearField && [yearField respondsTo:@selector(setIntValue:)])
  158.       [yearField setIntValue:[[calendarMatrix dateDelegate] year]];
  159.  
  160.     /* If we are displaying the standard year header, set its value */
  161.     /* to the year */
  162.  
  163.     if (displayYearHeader)
  164.       [yearSubview setIntValue:[[calendarMatrix dateDelegate]
  165.                 year]];
  166.  
  167.     if (displayMonthAndYearHeader)
  168.     {
  169.     [inlineMonthSubview setStringValue:[[calendarMatrix dateDelegate]
  170.                         monthStringValue]];
  171.  
  172.     [inlineYearSubview setIntValue:[[calendarMatrix dateDelegate]
  173.                     year]];
  174.     }
  175.  
  176.     /* If there is a date field, set its value to the curent date */
  177.  
  178.     if (dateField && [dateField respondsTo:@selector(setStringValue:)])
  179.       [dateField setStringValue:[[calendarMatrix dateDelegate]
  180.                  dateStringValue]];
  181.  
  182.     return self;
  183. }
  184.  
  185. - initFrame:(const NXRect *)frameRect
  186. {
  187.     NXRect     subViewFrame;
  188.     id        newSubview;
  189.     calHeaders    *headers;
  190.     const char *pbTypes[] = {NXColorPboardType};
  191.  
  192.     [super initFrame:frameRect];
  193.  
  194.     helvetica_11 = [Font newFont:"Helvetica" size:11 style:0
  195.                    matrix:NX_FLIPPEDMATRIX];
  196.     system_11_bold = [Font boldSystemFontOfSize:11
  197.               matrix:NX_FLIPPEDMATRIX];
  198.  
  199.     helvetica_12 = [Font newFont:"Helvetica" size:12 style:0
  200.                    matrix:NX_FLIPPEDMATRIX];
  201.     system_12_bold = [Font boldSystemFontOfSize:12
  202.               matrix:NX_FLIPPEDMATRIX];
  203.  
  204.     [self registerForDraggedTypes:pbTypes count:1];
  205.     [[self window] registerForDraggedTypes:pbTypes count:1];
  206.  
  207.     colorDragAndDrop = NO;
  208.  
  209.     /* The list of textfield cells that holds the day of the week */
  210.     /* headings */
  211.  
  212.     dowSubviewList = [[List alloc] init];
  213.  
  214.     displayDOWHeader = YES;
  215.     displayMonthHeader = NO;
  216.     displayYearHeader = NO;
  217.     displayMonthAndYearHeader = NO;
  218.  
  219.     headers = headerSpecs;
  220.  
  221.     /* static view information for day-of-the-week textfield headers */
  222.  
  223.     NXSetRect(&subViewFrame, DEFAULT_MATRIX_XPOS+1, DEFAULT_HEADER_YPOS,
  224.           DEFAULT_MATRIX_WIDTH, DEFAULT_HEADER_HEIGHT);
  225.          
  226.     /* Create the day of the week headers (S, M, T, W...) */
  227.  
  228.     while(headers->xdelta > -1)
  229.     {
  230.       NX_X(&subViewFrame) += headers->xdelta;
  231.       NX_WIDTH(&subViewFrame) = headers->width;
  232.  
  233.       newSubview = [self _createTextFieldWithFrame:&subViewFrame
  234.             stringValue:headers->value];
  235.  
  236.       [dowSubviewList addObject:newSubview];
  237.  
  238.       [self addSubview:newSubview];
  239.  
  240.       headers++;
  241.     }
  242.  
  243.     /* Create the month and year textfield headers */
  244.  
  245.     NXSetRect(&subViewFrame, DEFAULT_MATRIX_XPOS+1, DEFAULT_HEADER_YPOS,
  246.           DEFAULT_MATRIX_WIDTH, DEFAULT_HEADER_HEIGHT);
  247.  
  248.     monthSubview = [self _createTextFieldWithFrame:&subViewFrame
  249.             stringValue:"Month"];
  250.  
  251.     yearSubview = [self _createTextFieldWithFrame:&subViewFrame
  252.            stringValue:"Year"];
  253.  
  254.     [Font setUserFont:helvetica_12];
  255.  
  256.     [monthSubview setFont:system_12_bold];
  257.  
  258.     [yearSubview setFont:system_12_bold];
  259.  
  260.     /* Create the month and year textfield headers, where the month */
  261.     /* and year are on the same line */
  262.  
  263.     NXSetRect(&subViewFrame, DEFAULT_MATRIX_XPOS+1, DEFAULT_HEADER_YPOS,
  264.           (int)(DEFAULT_MATRIX_WIDTH/2), DEFAULT_HEADER_HEIGHT);
  265.  
  266.     inlineMonthSubview = [self _createTextFieldWithFrame:&subViewFrame
  267.               stringValue:"Month"];
  268.  
  269.     [inlineMonthSubview setAlignment:NX_LEFTALIGNED];
  270.  
  271.     [inlineMonthSubview setFont:system_12_bold];
  272.  
  273.     NXSetRect(&subViewFrame, 
  274.           ((DEFAULT_MATRIX_WIDTH - (int)(DEFAULT_MATRIX_WIDTH/2) + 
  275.         DEFAULT_MATRIX_XPOS+1)), 
  276.           DEFAULT_HEADER_YPOS, (int)(DEFAULT_MATRIX_WIDTH/2),
  277.           DEFAULT_HEADER_HEIGHT);
  278.  
  279.     inlineYearSubview = [self _createTextFieldWithFrame:&subViewFrame
  280.              stringValue:"Year"];
  281.  
  282.     [inlineYearSubview setAlignment:NX_RIGHTALIGNED];
  283.  
  284.     [inlineYearSubview setFont:system_12_bold];
  285.  
  286.     /* Create the actual calendar matrix view with the given */
  287.     /* dimensions */
  288.  
  289.     NXSetRect(&subViewFrame, DEFAULT_MATRIX_XPOS, DEFAULT_MATRIX_YPOS,
  290.           DEFAULT_MATRIX_WIDTH, DEFAULT_MATRIX_HEIGHT);
  291.  
  292.     calendarMatrix = [[MiscCalendarMatrix alloc] initFrame:&subViewFrame];
  293.  
  294.     [calendarMatrix setAutosizing:NX_MINYMARGINSIZABLE | 
  295.      NX_MAXYMARGINSIZABLE | NX_WIDTHSIZABLE | NX_HEIGHTSIZABLE];
  296.  
  297.     [calendarMatrix setAutosizeCells:YES];
  298.  
  299.     [calendarMatrix setAction:@selector(updateDate:)];
  300.     [calendarMatrix setTarget:self];
  301.  
  302.     if (dateDelegate)
  303.       [calendarMatrix setDateDelegate:dateDelegate];
  304.     else
  305.       dateDelegate = [calendarMatrix dateDelegate];
  306.  
  307.     previousDayCell = [calendarMatrix selectedCell];
  308.  
  309.     /* Added the calendar matrix to our view */
  310.  
  311.     [self addSubview:calendarMatrix];
  312.  
  313.     if (monthField && [monthField respondsTo:@selector(setStringValue:)])
  314.       [monthField setStringValue:[[calendarMatrix dateDelegate]
  315.                   monthStringValue]];
  316.  
  317.     if (yearField && [yearField respondsTo:@selector(setIntValue:)])
  318.       [yearField setIntValue:[[calendarMatrix dateDelegate] year]];
  319.  
  320.     if (dateField && [dateField respondsTo:@selector(setStringValue:)])
  321.       [dateField setStringValue:[[calendarMatrix dateDelegate]
  322.                  dateStringValue]];
  323.  
  324.     NX_WIDTH(&defaultFrame) = frameRect->size.width;
  325.     NX_HEIGHT(&defaultFrame) = frameRect->size.height;
  326.  
  327.     return self;
  328. }
  329.  
  330. - getMinSize:(NXSize *)minSize maxSize:(NXSize *)maxSize from:(int)where
  331. {
  332.     /* The view is not sizable at this time */
  333.  
  334.     minSize->width = NX_WIDTH(&defaultFrame);
  335.     minSize->height = NX_HEIGHT(&defaultFrame);
  336.  
  337.     maxSize->width = NX_WIDTH(&defaultFrame);
  338.     maxSize->height = NX_HEIGHT(&defaultFrame);
  339.  
  340.     return self;
  341. }
  342.  
  343. - calendarMatrix
  344. {
  345.     return calendarMatrix;
  346. }
  347.  
  348. - preserveCellColors:(BOOL)yn
  349. {
  350.     [calendarMatrix overwriteCellColors:yn];
  351.  
  352.     return self;
  353. }
  354.  
  355. - (BOOL)cellColorsPreserved
  356. {
  357.     return [calendarMatrix cellColorsOverwritten];
  358. }
  359.  
  360. - setColorOf:(int)element to:(NXColor)aColor forCellAt:(int)xPos :(int)yPos
  361. {
  362.     switch (element)
  363.     {
  364.       case MISC_CV_CELLBACKGROUND:
  365.     [calendarMatrix setBackgroundColor:aColor forCellAt:xPos :yPos];
  366.     [calendarMatrix display];
  367.     break;
  368.  
  369.       case MISC_CV_CELLTEXT:
  370.     [calendarMatrix setTextColor:aColor forCellAt:xPos :yPos];
  371.     [calendarMatrix display];
  372.     break;
  373.  
  374.       case MISC_CV_CELLHIGHLIGHT:
  375.     [calendarMatrix setHighlightColor:aColor forCellAt:xPos :yPos];
  376.     [calendarMatrix display];
  377.     break;
  378.  
  379.       case MISC_CV_CELLTEXTHIGHLIGHT:
  380.     [calendarMatrix setHighlightTextColor:aColor forCellAt:xPos :yPos];
  381.     [calendarMatrix display];
  382.     break;
  383.  
  384.       default:
  385.     break;
  386.     }
  387.     
  388.     return self;
  389. }
  390.  
  391. - (NXColor)colorOf:(int)element forCellAt:(int)xPos :(int)yPos
  392. {
  393.     NXColor color;
  394.  
  395.     color = NX_COLORBLACK;
  396.  
  397.     switch (element)
  398.     {
  399.       case MISC_CV_CELLBACKGROUND:
  400.     color = [calendarMatrix backgroundColorForCellAt:xPos :yPos];
  401.     break;
  402.  
  403.       case MISC_CV_CELLTEXT:
  404.     color = [calendarMatrix textColorForCellAt:xPos :yPos];
  405.     break;
  406.  
  407.       case MISC_CV_CELLHIGHLIGHT:
  408.     color = [calendarMatrix highlightColorForCellAt:xPos :yPos];
  409.     break;
  410.  
  411.       case MISC_CV_CELLTEXTHIGHLIGHT:
  412.     color =[calendarMatrix highlightTextColorForCellAt:xPos :yPos];
  413.     break;
  414.  
  415.       default:
  416.     break;
  417.     }
  418.     
  419.     return color;
  420. }
  421.  
  422. - setColorOf:(int)element to:(NXColor)aColor
  423. {
  424.     switch (element)
  425.     {
  426.       case MISC_CV_CELLBACKGROUND:
  427.     [calendarMatrix setCellBackgroundColor:aColor];
  428.     [calendarMatrix display];
  429.     break;
  430.  
  431.       case MISC_CV_CELLTEXT:
  432.     [calendarMatrix setCellTextColor:aColor];
  433.     [calendarMatrix display];
  434.     break;
  435.  
  436.       case MISC_CV_CELLHIGHLIGHT:
  437.     [calendarMatrix setCellHighlightColor:aColor];
  438.     [calendarMatrix display];
  439.     break;
  440.  
  441.       case MISC_CV_CELLTEXTHIGHLIGHT:
  442.     [calendarMatrix setCellHighlightTextColor:aColor];
  443.     [calendarMatrix display];
  444.     break;
  445.  
  446.       case MISC_CV_MONTHHEADER:
  447.     [monthSubview setTextColor:aColor];
  448.     [monthSubview display];
  449.     break;
  450.  
  451.       case MISC_CV_YEARHEADER:
  452.     [yearSubview setTextColor:aColor];
  453.     [yearSubview display];
  454.     break;
  455.  
  456.       case MISC_CV_INLINEMONTHHEADER:
  457.     [inlineMonthSubview setTextColor:aColor];
  458.     [inlineMonthSubview display];
  459.     break;
  460.  
  461.       case MISC_CV_INLINEYEARHEADER:
  462.     [inlineYearSubview setTextColor:aColor];
  463.     [inlineYearSubview display];
  464.     break;
  465.  
  466.       default:
  467.     break;
  468.     }
  469.     
  470.     return self;
  471. }
  472.  
  473. - (NXColor)colorOf:(int)element
  474. {
  475.     NXColor color;
  476.  
  477.     switch (element)
  478.     {
  479.       case MISC_CV_CELLBACKGROUND:
  480.     color = [calendarMatrix cellBackgroundColor];
  481.     break;
  482.  
  483.       case MISC_CV_CELLTEXT:
  484.     color = [calendarMatrix cellTextColor];
  485.     break;
  486.  
  487.       case MISC_CV_CELLHIGHLIGHT:
  488.     color = [calendarMatrix cellHighlightColor];
  489.     break;
  490.  
  491.       case MISC_CV_CELLTEXTHIGHLIGHT:
  492.     color = [calendarMatrix cellHighlightTextColor];
  493.     break;
  494.  
  495.       case MISC_CV_MONTHHEADER:
  496.     color = [monthSubview textColor];
  497.     break;
  498.  
  499.       case MISC_CV_YEARHEADER:
  500.     color = [yearSubview textColor];
  501.     break;
  502.  
  503.       case MISC_CV_INLINEMONTHHEADER:
  504.     color = [inlineMonthSubview textColor];
  505.     break;
  506.  
  507.       case MISC_CV_INLINEYEARHEADER:
  508.     color = [inlineYearSubview textColor];
  509.     break;
  510.  
  511.       default:
  512.     color = NX_COLORBLACK;
  513.     break;
  514.     }
  515.     
  516.     return color;
  517. }
  518.  
  519. - cellAt:(int)xPos :(int)yPos lock:(BOOL)yn
  520. {
  521.     [[calendarMatrix cellAt:xPos :yPos] setEnabled:yn];
  522.  
  523.     return self;
  524. }
  525.  
  526. - forRow:(int)row lock:(BOOL)yn
  527. {
  528.     int i;
  529.  
  530.     for (i = 0; i < NUM_MATRIX_COLS; i++)
  531.       [self cellAt:row :i lock:yn];
  532.  
  533.     return self;
  534. }
  535.  
  536. - forColumn:(int)col lock:(BOOL)yn
  537. {
  538.     int i;
  539.  
  540.     for (i = 0; i < NUM_MATRIX_ROWS; i++)
  541.       [self cellAt:i :col lock:yn];
  542.  
  543.     return self;
  544. }
  545.  
  546. - setHighlightMode:(int)mode
  547. {
  548.     return [calendarMatrix setMode:mode];
  549. }
  550.  
  551. - (int)highlightMode
  552. {
  553.     return [calendarMatrix mode];
  554. }
  555.  
  556. - allowColorDragAndDrop:(BOOL)yn
  557. {
  558.     colorDragAndDrop = yn;
  559.  
  560.     return self;
  561. }
  562.  
  563. - (BOOL)canDragAndDropColor
  564. {
  565.     return colorDragAndDrop;
  566. }
  567.  
  568. - forHeader:(int)aHeader display:(BOOL)doDisplay
  569. {
  570.     int        yOffset,
  571.         i;
  572.     
  573.     NX_HEIGHT(&defaultFrame) += doDisplay ? DEFAULT_HEADER_HEIGHT : 
  574.       -DEFAULT_HEADER_HEIGHT;
  575.  
  576.     [self sizeBy:0 :(doDisplay ? DEFAULT_HEADER_HEIGHT : 
  577.              -DEFAULT_HEADER_HEIGHT)];
  578.     
  579.     yOffset = doDisplay ? DEFAULT_HEADER_HEIGHT :
  580.       -DEFAULT_HEADER_HEIGHT;
  581.       
  582.     switch (aHeader)
  583.     {
  584.       case MISC_CV_DOWHEADER:
  585.     displayDOWHeader = doDisplay;
  586.  
  587.     if (displayMonthAndYearHeader)
  588.     {
  589.         [inlineMonthSubview moveBy:0 :yOffset];
  590.         [inlineYearSubview moveBy:0 :yOffset];
  591.     }
  592.  
  593.     if (displayMonthHeader)
  594.       [monthSubview moveBy:0 :yOffset];
  595.  
  596.     if (displayYearHeader)
  597.       [yearSubview moveBy:0 :yOffset];
  598.     
  599.     if (displayDOWHeader)
  600.       for (i = 0; i < [dowSubviewList count]; i++)
  601.         [self addSubview:[dowSubviewList objectAt:i]];
  602.     else
  603.         for (i = 0; i < [dowSubviewList count]; i++)
  604.           [[dowSubviewList objectAt:i] removeFromSuperview];
  605.  
  606.     break;
  607.  
  608.       case MISC_CV_MONTHANDYEARHEADER:
  609.     displayMonthAndYearHeader = doDisplay;
  610.     
  611.     if (displayYearHeader)
  612.       [yearSubview moveBy:0 :yOffset];
  613.  
  614.     if (displayMonthHeader)
  615.       [monthSubview moveBy:0 :yOffset];
  616.  
  617.     if (displayDOWHeader)
  618.     {
  619.         [inlineMonthSubview moveBy:0 :yOffset];
  620.         [inlineYearSubview moveBy:0 :yOffset];
  621.     }
  622.  
  623.     if (displayMonthAndYearHeader)
  624.     {
  625.         [self addSubview:inlineMonthSubview];
  626.         [self addSubview:inlineYearSubview];
  627.     }
  628.     else
  629.     {
  630.         [inlineMonthSubview removeFromSuperview];
  631.         [inlineYearSubview removeFromSuperview];
  632.     }
  633.  
  634.     break;
  635.  
  636.       case MISC_CV_MONTHHEADER:
  637.     displayMonthHeader = doDisplay;
  638.  
  639.     if (displayYearHeader)
  640.       [yearSubview moveBy:0 :yOffset];
  641.  
  642.     if (displayDOWHeader)
  643.       [monthSubview moveBy:0 :yOffset];
  644.  
  645.     if (displayMonthAndYearHeader)
  646.       [monthSubview moveBy:0 :yOffset];
  647.  
  648.     if (displayMonthHeader)
  649.       [self addSubview:monthSubview];
  650.     else
  651.       [monthSubview removeFromSuperview];
  652.  
  653.     break;
  654.  
  655.       case MISC_CV_YEARHEADER:
  656.     displayYearHeader = doDisplay;
  657.  
  658.     if (displayDOWHeader)
  659.       [yearSubview moveBy:0 :yOffset];
  660.  
  661.     if (displayMonthAndYearHeader)
  662.       [yearSubview moveBy:0 :yOffset];
  663.  
  664.     if (displayMonthHeader)
  665.       [yearSubview moveBy:0 :yOffset];
  666.  
  667.     if (displayYearHeader)
  668.       [self addSubview:yearSubview];
  669.     else
  670.       [yearSubview removeFromSuperview];
  671.  
  672.     break;
  673.     
  674.       default:
  675.     NX_HEIGHT(&defaultFrame) += !doDisplay ? DEFAULT_HEADER_HEIGHT : 
  676.       -DEFAULT_HEADER_HEIGHT;
  677.  
  678.     [self sizeBy:0 :(!doDisplay ? DEFAULT_HEADER_HEIGHT : 
  679.              -DEFAULT_HEADER_HEIGHT)];
  680.     
  681.     break;
  682.     }
  683.  
  684.     return self;
  685. }
  686.  
  687. - (BOOL)isHeaderDisplayed:(int)aHeader;
  688. {
  689.     switch (aHeader)
  690.     {
  691.       case MISC_CV_DOWHEADER:
  692.     return displayDOWHeader;
  693.     break;
  694.     
  695.       case MISC_CV_MONTHHEADER:
  696.     return displayMonthHeader;
  697.     break;
  698.  
  699.       case MISC_CV_YEARHEADER:
  700.     return displayYearHeader;
  701.     break;
  702.  
  703.       case MISC_CV_MONTHANDYEARHEADER:
  704.     return displayMonthAndYearHeader;
  705.     break;
  706.  
  707.       default:
  708.     return NO;
  709.     }
  710. }
  711.  
  712. - setColorTo:(NXColor)aColor forDay:(MiscCVDays)aDay
  713. {
  714.     return [[[dowSubviewList objectAt:aDay] setTextColor:aColor] display];
  715. }
  716.  
  717. - (NXColor)colorForDay:(MiscCVDays)aDay
  718. {
  719.     return [[dowSubviewList objectAt:aDay] textColor];
  720. }
  721.  
  722. - incrementMonth:sender
  723. {
  724.     id date;
  725.  
  726.     date = [calendarMatrix dateDelegate];
  727.  
  728.     [date incrementMonth];
  729.  
  730.     [self updateDate:self];
  731.  
  732.     previousDayCell = [calendarMatrix selectedCell];
  733.  
  734.     return self;
  735. }
  736.  
  737. - decrementMonth:sender
  738. {
  739.     id date;
  740.  
  741.     date = [calendarMatrix dateDelegate];
  742.  
  743.     [date decrementMonth];
  744.  
  745.     [self updateDate:self];
  746.  
  747.     previousDayCell = [calendarMatrix selectedCell];
  748.  
  749.     return self;
  750. }
  751.  
  752. - incrementYear:sender
  753. {
  754.     id date;
  755.  
  756.     date = [calendarMatrix dateDelegate];
  757.  
  758.     [date incrementYear];
  759.  
  760.     [self updateDate:self];
  761.  
  762.     previousDayCell = [calendarMatrix selectedCell];
  763.  
  764.     return self;
  765. }
  766.  
  767. - decrementYear:sender
  768. {
  769.     id date;
  770.  
  771.     date = [calendarMatrix dateDelegate];
  772.  
  773.     [date decrementYear];
  774.  
  775.     [self updateDate:self];
  776.  
  777.     previousDayCell = [calendarMatrix selectedCell];
  778.  
  779.     return self;
  780. }
  781.  
  782. - updateDate:sender
  783. {
  784.     DateSelectionCell    *dayCell;
  785.     id            date;
  786.     int            day,
  787.             month,
  788.             year;
  789.  
  790.     if (!(dayCell = [calendarMatrix selectedCell]))
  791.     {
  792.     if (previousDayCell)
  793.       [calendarMatrix selectCell:previousDayCell];
  794.  
  795.     return nil;
  796.     }
  797.  
  798.     dayCell = [calendarMatrix selectedCell];
  799.  
  800.     previousDayCell = dayCell;
  801.  
  802.     date = [calendarMatrix dateDelegate];
  803.  
  804.     day = [dayCell intValue];
  805.     month = [date month];
  806.     year = [date year];
  807.  
  808.     [date setYear:year month:month day:day];
  809.  
  810.     [self displayDate:self];
  811.  
  812.     return self;
  813. }
  814.  
  815. - displayDate:sender
  816. {
  817.     if (monthField && [monthField respondsTo:@selector(setStringValue:)])
  818.       [monthField setStringValue:[[calendarMatrix dateDelegate]
  819.                   monthStringValue]];
  820.  
  821.     if (displayMonthHeader)
  822.       [monthSubview setStringValue:[[calendarMatrix dateDelegate]
  823.                     monthStringValue]];
  824.  
  825.     if (yearField && [yearField respondsTo:@selector(setIntValue:)])
  826.       [yearField setIntValue:[[calendarMatrix dateDelegate] year]];
  827.  
  828.     if (displayYearHeader)
  829.       [yearSubview setIntValue:[[calendarMatrix dateDelegate]
  830.                 year]];
  831.  
  832.     if (dateField && [dateField respondsTo:@selector(setStringValue:)])
  833.       [dateField setStringValue:[[calendarMatrix dateDelegate]
  834.                  dateStringValue]];
  835.  
  836.     if (displayMonthAndYearHeader)
  837.     {
  838.     [inlineMonthSubview setStringValue:[[calendarMatrix dateDelegate]
  839.                         monthStringValue]];
  840.  
  841.     [inlineYearSubview setIntValue:[[calendarMatrix dateDelegate]
  842.                     year]];
  843.     }
  844.  
  845.     [calendarMatrix displayDate:sender];
  846.  
  847.     return self;
  848. }
  849.  
  850. - setDateDelegate:(id <DateDelegate>)anObject
  851. {
  852.     dateDelegate = anObject;
  853.     [calendarMatrix setDateDelegate:dateDelegate];
  854.     
  855.     return self;
  856. }
  857.  
  858. - (id <DateDelegate>)dateDelegate
  859. {
  860.     return dateDelegate;
  861. }
  862.  
  863. - (const char *)getInspectorClassName
  864. {
  865.     return "MiscCalendarViewInspector";
  866. }
  867.  
  868. - (const char *)getEditorClassName
  869. {
  870.     return "MiscCalendarViewEditor";
  871. }
  872.  
  873. - read:(NXTypedStream *)aStream
  874. {
  875.     float    width,
  876.         height;
  877.  
  878.     [super read:aStream];
  879.  
  880.     NXReadTypes(aStream, "fficcccc@@@@@@@@@@@", &width, &height,
  881.         &titleDisplayMode, &displayDOWHeader, &displayMonthHeader, 
  882.         &displayYearHeader, &displayMonthAndYearHeader,
  883.         &colorDragAndDrop,
  884.         &calendarMatrix, &monthField, &previousDayCell, &monthSubview,
  885.         &dateDelegate, &yearField, &dateField, &dowSubviewList, 
  886.         &yearSubview, &inlineMonthSubview, &inlineYearSubview);
  887.  
  888.     NX_WIDTH(&defaultFrame) = width;
  889.     NX_HEIGHT(&defaultFrame) = height;
  890.  
  891.     return self;
  892. }
  893.  
  894. - write:(NXTypedStream *)aStream
  895. {
  896.     [super write:aStream];
  897.  
  898.     NXWriteTypes(aStream, "fficcccc@@@@@@@@@@@", &(NX_WIDTH(&defaultFrame)),
  899.          &(NX_HEIGHT(&defaultFrame)), &titleDisplayMode, 
  900.          &displayDOWHeader, &displayMonthHeader, &displayYearHeader,
  901.          &displayMonthAndYearHeader, &colorDragAndDrop, 
  902.          &calendarMatrix, &monthField,
  903.          &previousDayCell, &monthSubview, &dateDelegate, &yearField,
  904.          &dateField, &dowSubviewList, &yearSubview, 
  905.          &inlineMonthSubview, &inlineYearSubview);
  906.  
  907.     return self;
  908. }
  909.  
  910. @end
  911.  
  912. @implementation MiscCalendarView (TextDelegate)
  913.  
  914. - (BOOL)textWillChange:sender
  915. {
  916.     if (textDelegate && [textDelegate respondsTo:@selector(textWillChange:)])
  917.       return [textDelegate textWillChange:sender];
  918.     else
  919.       return NO;
  920. }
  921.  
  922. - textDidChange:sender
  923. {
  924.     if (textDelegate && [textDelegate respondsTo:@selector(textDidChange:)])
  925.       return [textDelegate textDidChange:sender];
  926.     else
  927.       return self;
  928. }
  929.  
  930. - (BOOL)textWillEnd:sender
  931. {
  932.     if (textDelegate && [textDelegate respondsTo:@selector(textWillEnd:)])
  933.       return [textDelegate textWillEnd:sender];
  934.     else
  935.       return NO;
  936. }
  937.  
  938. - textDidEnd:sender endChar:(unsigned short)whyEnd
  939. {
  940.     id retCode = self;
  941.  
  942.     if (textDelegate && [textDelegate 
  943.              respondsTo:@selector(textDidEnd:endChar:)])
  944.     {
  945.     retCode = [textDelegate textDidEnd:sender endChar:whyEnd];
  946.  
  947.     [self updateDate:self];
  948.     }
  949.  
  950.     return retCode;
  951. }
  952.  
  953. - textDidGetKeys:sender isEmpty:(BOOL)flag
  954. {
  955.     if (textDelegate && [textDelegate 
  956.              respondsTo:@selector(textDidGetKeys:isEmpty:)])
  957.       return [textDelegate textDidGetKeys:sender isEmpty:flag];
  958.     else
  959.       return self;
  960. }
  961.  
  962. @end
  963.  
  964. @implementation MiscCalendarView (Dragging)
  965.  
  966. - (NXDragOperation)draggingEntered:(id <NXDraggingInfo>)sender
  967. {
  968.     NXRect    aRect;
  969.     NXPoint    mouseLocation;
  970.  
  971.     if (([sender draggingSourceOperationMask] & NX_DragOperationCopy) &&
  972.     colorDragAndDrop)
  973.     {
  974.     NXSetRect(&aRect, DEFAULT_MATRIX_XPOS+1, DEFAULT_HEADER_YPOS,
  975.           DEFAULT_MATRIX_WIDTH, 0);
  976.  
  977.     if (displayDOWHeader)
  978.       NX_HEIGHT(&aRect) += DEFAULT_HEADER_HEIGHT;
  979.  
  980.     if (displayMonthAndYearHeader)
  981.       NX_HEIGHT(&aRect) += DEFAULT_HEADER_HEIGHT;
  982.  
  983.     if (displayMonthHeader)
  984.       NX_HEIGHT(&aRect) += DEFAULT_HEADER_HEIGHT;
  985.  
  986.     if (displayYearHeader)
  987.       NX_HEIGHT(&aRect) += DEFAULT_HEADER_HEIGHT;
  988.  
  989.     mouseLocation = [sender draggingLocation];
  990.  
  991.     [self convertPoint:&mouseLocation toView:self];
  992.  
  993.     if (NXMouseInRect(&mouseLocation, &aRect, NO))
  994.       return NX_DragOperationCopy;
  995.     }
  996.  
  997.     return NX_DragOperationNone;
  998. }
  999.  
  1000. - draggingExited:(id <NXDraggingInfo>)sender
  1001. {
  1002.     return self;
  1003. }
  1004.  
  1005. - (NXDragOperation)draggingUpdated:(id <NXDraggingInfo>)sender
  1006. {
  1007.     return [self draggingEntered:sender];
  1008. }
  1009.  
  1010. - (BOOL)prepareForDragOperation:(id <NXDraggingInfo>)sender
  1011. {
  1012.     if ([self draggingEntered:sender] == NX_DragOperationCopy)
  1013.       return YES;
  1014.  
  1015.     return NO;
  1016. }
  1017.  
  1018. - (BOOL)performDragOperation:(id <NXDraggingInfo>)sender
  1019. {
  1020.     NXColor    color;
  1021.     NXPoint    mouseLocation;
  1022.  
  1023.     color = NXReadColorFromPasteboard([sender draggingPasteboard]);
  1024.     
  1025.     mouseLocation = [sender draggingLocation];
  1026.     
  1027.     if ([self _acceptColor:color at:&mouseLocation])
  1028.       return YES;
  1029.  
  1030.     return NO;
  1031. }
  1032.  
  1033. - concludeDragOperation:(id <NXDraggingInfo>)sender
  1034. {
  1035.     return self;
  1036. }
  1037.  
  1038. @end
  1039.  
  1040. /* Satan made me do it! Okay, well, maybe not, but jeez NeXT, if you */
  1041. /* would just publish some of these APIs so us lowly end-user programmer */
  1042. /* could do all the neat things you get to do, ugly rule-breaking hacks */
  1043. /* like this would not happen. sigh.... Anyway, these two methods allow */
  1044. /* my view to accept drag-and-drop color in IB, just like textfield does. */
  1045. /* Thanks to the person who wrote ClassDump and Robert Nicholson for */
  1046. /* helping me find these... */
  1047.  
  1048. @implementation MiscCalendarView (IBView)
  1049.  
  1050. - depositIBColor:(NXColor)aColor at:(NXPoint *)aPoint
  1051. {
  1052.     NXPoint    mouseLocation;
  1053.     int        cellColorSelection;
  1054.  
  1055.     mouseLocation.x = aPoint->x;
  1056.     mouseLocation.y = aPoint->y;
  1057.  
  1058.     if (![self _acceptColor:aColor at:&mouseLocation])
  1059.     {
  1060.     cellColorSelection = [[[[NXApp getInspectorFor:self owner:self] 
  1061.                   cellColorMatrix] selectedCell] tag];
  1062.  
  1063.     [self setColorOf:cellColorSelection to:aColor];
  1064.     }
  1065.  
  1066.     return self;
  1067. }
  1068.  
  1069. - acceptsIBColorAt:(NXPoint *)aPoint;
  1070. {
  1071.     return self;
  1072. }
  1073.  
  1074. @end
  1075.  
  1076. @implementation MiscCalendarView (Private)
  1077.  
  1078. - _createTextFieldWithFrame:(NXRect *)textFrame 
  1079.   stringValue:(const char *)aString
  1080. {
  1081.     TextField    *textField;
  1082.  
  1083.     textField = [[TextField alloc] initFrame:textFrame];
  1084.     [textField setEditable:NO];
  1085.     [textField setBezeled:NO];
  1086.     [textField setBordered:NO];
  1087.     [textField setSelectable:NO];
  1088.     [textField setAlignment:NX_CENTERED];
  1089.     [textField setBackgroundGray:-1];
  1090.     
  1091.     [textField setAutosizing:NX_MINYMARGINSIZABLE | 
  1092.      NX_MAXYMARGINSIZABLE | NX_WIDTHSIZABLE | NX_HEIGHTSIZABLE];
  1093.  
  1094.     [Font setUserFont:helvetica_11];
  1095.  
  1096.     [textField setFont:system_11_bold];
  1097.  
  1098.     [textField setStringValue:aString];
  1099.  
  1100.     return textField;
  1101. }
  1102.  
  1103. - _acceptColor:(NXColor)aColor at:(NXPoint *)aPoint
  1104. {
  1105.     TextField    *textField;
  1106.     NXPoint    mouseLocation;
  1107.     NXRect    aRect;
  1108.     int     i;
  1109.  
  1110.     mouseLocation.x = aPoint->x;
  1111.     mouseLocation.y = aPoint->y;
  1112.  
  1113.     textField = nil;
  1114.  
  1115.     [self convertPoint:&mouseLocation fromView:[self superview]];
  1116.  
  1117.     if (displayDOWHeader)
  1118.       for (i = 0; i < [dowSubviewList count]; i++)
  1119.       {
  1120.       [[dowSubviewList objectAt:i] getFrame:&aRect];
  1121.  
  1122.       if (NXMouseInRect(&mouseLocation, &aRect, NO))
  1123.       {
  1124.           textField = [dowSubviewList objectAt:i];
  1125.           i = [dowSubviewList count];
  1126.       }
  1127.       }
  1128.  
  1129.     if (!textField && displayMonthAndYearHeader)
  1130.     {
  1131.     [inlineMonthSubview getFrame:&aRect];
  1132.  
  1133.       if (NXMouseInRect(&mouseLocation, &aRect, NO))
  1134.         textField = inlineMonthSubview;
  1135.     }
  1136.  
  1137.     if (!textField && displayMonthAndYearHeader)
  1138.     {
  1139.     [inlineYearSubview getFrame:&aRect];
  1140.  
  1141.       if (NXMouseInRect(&mouseLocation, &aRect, NO))
  1142.         textField = inlineYearSubview;
  1143.     }
  1144.  
  1145.     if (!textField && displayMonthHeader)
  1146.     {
  1147.     [monthSubview getFrame:&aRect];
  1148.  
  1149.       if (NXMouseInRect(&mouseLocation, &aRect, NO))
  1150.         textField = monthSubview;
  1151.     }
  1152.  
  1153.     if (!textField && displayYearHeader)
  1154.     {
  1155.     [yearSubview getFrame:&aRect];
  1156.  
  1157.       if (NXMouseInRect(&mouseLocation, &aRect, NO))
  1158.         textField = yearSubview;
  1159.     }
  1160.  
  1161.     if (textField)
  1162.     {
  1163.     [textField setTextColor:aColor];
  1164.     return self;
  1165.     }
  1166.     
  1167.     return nil;
  1168. }
  1169.  
  1170. @end
  1171.  
  1172.